package link

import (
	"fmt"
	"math/rand"
	"time"
)

type CircularDoubleLinkedList struct {
	Head *DoubleLinkedNode
}

func NewCircularDoubleLinkedList() *CircularDoubleLinkedList {
	return &CircularDoubleLinkedList{Head: NewDoubleLinkedNode(0)}
}

func (cdll *CircularDoubleLinkedList) CreateCircularDoubleLinkedList(nlen int) {
	rand.Seed(time.Now().Unix())
	cNode := cdll.Head
	for i := 0; i < nlen; i++ {
		node := NewDoubleLinkedNode(rand.Intn(100) + 1)
		cNode.Next = node
		node.Prev = cNode
		node.Next = cdll.Head
		cdll.Head.Prev = node
		cNode = cNode.Next
	}
}

func (cdll *CircularDoubleLinkedList) TravelCircularDoubleLinkedList() {
	cNode := cdll.Head
	fmt.Printf("该节点为：head")
	for cNode.Next != cdll.Head {
		if cNode.Data != 0 {
			fmt.Printf("->%v", cNode.Data)
		}
		cNode = cNode.Next
	}
	fmt.Printf("->%v\n", cNode.Data)
}

func (cdll *CircularDoubleLinkedList) InsertElementInHead() {
	cNode := cdll.Head
	rand.Seed(time.Now().Unix())
	num := rand.Intn(100) + 1
	fmt.Println("头插法，插入元素：", num)
	node := NewDoubleLinkedNode(num)
	node.Next = cNode.Next
	cNode.Next.Prev = node
	cNode.Next = node
	node.Prev = cNode
}

func (cdll *CircularDoubleLinkedList) InsertElementInTail() {
	cNode := cdll.Head
	rand.Seed(time.Now().Unix())
	num := rand.Intn(100) + 1
	fmt.Println("尾插法，插入元素：", num)
	node := NewDoubleLinkedNode(num)
	for cNode.Next != cdll.Head {
		cNode = cNode.Next
	}
	node.Next = cdll.Head
	cdll.Head.Prev = node
	cNode.Next = node
	node.Prev = cNode
}

func (cdll *CircularDoubleLinkedList) FindElemnentByPos(pos int) *DoubleLinkedNode {
	cNode := cdll.Head
	ppos := 0
	for cNode.Next != cdll.Head {
		if ppos == pos {
			return cNode
		}
		ppos += 1
		cNode = cNode.Next
	}
	return nil
}

func (cdll *CircularDoubleLinkedList) FindElemnentPreNode(num int) *DoubleLinkedNode {
	cNode := cdll.Head
	var preNode *DoubleLinkedNode
	for cNode.Next != cdll.Head {
		if cNode.Data == num {
			return preNode
		}
		preNode = cNode
		cNode = cNode.Next
	}
	return nil
}

func (cdll *CircularDoubleLinkedList) DeleteElement(num int) {
	fmt.Println("待删除元素： ", num)
	preNode := cdll.FindElemnentPreNode(num)
	preNode.Next = preNode.Next.Next
	preNode.Next.Next.Prev = preNode
}
